/*
 * @Author: your name
 * @Date: 2021-10-22 12:54:50
 * @LastEditTime: 2021-10-22 12:54:50
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /Desktop/test.c
 */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int sudoku[30][9];
bool verification[11]; 
int squnum = 2; 
void *checkpar(void *parameterss) ;
void *checkrow(void *parameterss);
void *checkcolumn(void *parameterss);
typedef struct {   
    int row;
    int column;
} parameters;

pthread_t columns, rows, par1, par2, par3, par4, par5, par6, par7, par8, par9;



int main(int argc, char *argv[]) {
	int i=0;
	int j=0;
	int k=0;
	if(argc == 1){
		fprintf(stderr, "usage ./pa3 sudoku.txt");
		return -1;
	}
	char temp[50];
	FILE *fp;
	fp = fopen(argv[1],"r");
	for(i=0;i<9;i++){
			fgets(temp,50,fp);
			for(j = 0; j<17; j++){
				if(temp[j] == ','){
					
				}else{
					sudoku[i][k] = temp[j]-48;
					printf("%d  ", sudoku[i][k]);
					k++;
				}
			}
		printf("\n");
		}
    parameters *data = (parameters *) malloc(sizeof(parameters));
    data->row = 0;
    data->column = 0;
    pthread_create(&columns, NULL, checkcolumn, (void *) data);
    pthread_create(&rows, NULL, checkrow, (void *) data);
    pthread_create(&par1, NULL, checkpar, (void *) data);
    	data->row = 0;
    	data->column = 3;
    pthread_create(&par2, NULL, checkpar, (void *) data);
    	data->row = 0;
    	data->column = 6;
    pthread_create(&par3, NULL, checkpar, (void *) data);
    	data->row = 3;
    	data->column = 0;
    pthread_create(&par4, NULL, checkpar, (void *) data);
    	data->row = 3;
    	data->column = 3;
    pthread_create(&par5, NULL, checkpar, (void *) data);
    	data->row = 3;
    	data->column = 6;
    pthread_create(&par6, NULL, checkpar, (void *) data);
    	data->row = 6;
    	data->column = 0;
    pthread_create(&par7, NULL, checkpar, (void *) data);
    	data->row = 6;
    	data->column = 3;
    pthread_create(&par8, NULL, checkpar, (void *) data);
    	data->row = 6;
    	data->column = 6;
    pthread_create(&par9, NULL, checkpar, (void *) data);    
    pthread_join(columns, NULL);
    pthread_join(rows, NULL);
    pthread_join(par1, NULL);
    pthread_join(par2, NULL);
    pthread_join(par3, NULL);
    pthread_join(par4, NULL);
    pthread_join(par5, NULL);
    pthread_join(par6, NULL);
    pthread_join(par7, NULL);
    pthread_join(par8, NULL);
    pthread_join(par9, NULL);

    for (int k = 0; k < 11; ++k) {
        if (!verification[k]) {
            printf("\ninvalid sudoku solution\n");
            exit(0);
        }
    }
    printf("\nThis sudoku is valid.\n");
    return 0;
}
//use this to check colimn
void *checkcolumn(void *parameterss) {
	
    parameters *data = ( parameters *) parameterss;
    int col = data->column;
    int numr = data->row;
    
    for (int i = col; i < 9; i++) {
        int col[9] = {0}; 
        for (int j = numr; j < 9; j++) {
            int aux = sudoku[2*i][j];
            if (col[aux - 1] == 0 && aux > 0) { 
                col[aux - 1] = aux;     
            } else if (aux <= 0) {
                verification[0] = 0;
                pthread_exit(0);
            } else {
                verification[0] = 0;
                pthread_exit(0);
            }
        }
    }
    verification[0] = 1;
    pthread_exit(0); 
}

//use this to check row
void *checkrow(void *parameterss) {

    parameters *data = (parameters *) parameterss;
    int col = data->column;
    int numr = data->row;

    for (int i = col; i < 9; i++) {
        int row[9] = {0};
        for (int j = numr; j < 9; j++) {
            int aux = sudoku[2*i][j];
            if (row[aux - 1] == 0 && aux > 0) {
                row[aux - 1] = aux;
            } else if (aux <= 0) {
                verification[0] = 0;
                pthread_exit(0);
            } else {
                verification[0] = 0;
                pthread_exit(0);
            }
        }
    }
    verification[1] = 1;
    pthread_exit(0);
}

//use this to check every part
void *checkpar(void *parameterss) {

    parameters *data = (parameters *) parameterss;
    int numr = data->row;
    int col = data->column;
    int square[9] = {0};

    for (int i = col; i < col + 3; i++) {
        for (int j = numr; j < numr + 3; ++j) {
            int aux = sudoku[2*i][j];
            if (square[aux - 1] == 0 && aux > 0) {
                square[aux - 1] = aux;
            }
            else {
                verification[squnum] = 0;
                squnum++;
                pthread_exit(0);
            }
        }
    }
    verification[squnum] = 1;
    squnum++;
    pthread_exit(0);
}




